Ключи шардирования могут передаваться в запросе как явно, так и неявно, в виде комментариев.
В SPQR реализованы функции транзакционного и сессионного пулинга, автобалансировки шардированных таблиц, а также поддержка всех возможных методов аутентификации, сбора статистики и динамической перезагрузки конфигурации.
SPQR поддерживает как запросы к определённому шарду, так и запросы ко всем шардам. В ближайших планах — добавить поддержку двухфазных транзакций и референсных таблиц.
Исходный код SPQR распространяется под лицензией PostgreSQL Global Development Group
⚡️ Ссылки:
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
🗂️ BRModelo Web — веб-приложение для проектирования баз данных. Этот open-source проект позволяет создавать ER-диаграммы прямо в браузере с экспортом в SQL-скрипты.
Инструмент имеет образовательную направленность. Интерфейс на португальском и английском языках адаптирован для учебных задач: есть подсветка сущностей, автоматическая расстановка связей и валидация схемы. Запустить локальную копию можно через Node.js + MongoDB или Docker-контейнеры.
🤖 GitHub
@sqlhub
Инструмент имеет образовательную направленность. Интерфейс на португальском и английском языках адаптирован для учебных задач: есть подсветка сущностей, автоматическая расстановка связей и валидация схемы. Запустить локальную копию можно через Node.js + MongoDB или Docker-контейнеры.
🤖 GitHub
@sqlhub
🐘 pgBackRest — надежное решение для резервного копирования PostgreSQL. В отличие от стандартных утилит, pgBackRest предлагает параллельное выполнение операций, поддержку инкрементных бэкапов на уровне блоков и встроенную проверку целостности через контрольные суммы.
Особого внимания заслуживает гибкость развертывания: резервные копии можно хранить локально, на удаленных серверах через SSH/TLS или в облачных хранилищах S3/Azure/GCS. Система автоматически управляет ротацией архивов и обеспечивает консистентность данных даже при аварийном завершении работы.
🤖 GitHub
@sqlhub
Особого внимания заслуживает гибкость развертывания: резервные копии можно хранить локально, на удаленных серверах через SSH/TLS или в облачных хранилищах S3/Azure/GCS. Система автоматически управляет ротацией архивов и обеспечивает консистентность данных даже при аварийном завершении работы.
🤖 GitHub
@sqlhub
🛠️ История создания “storage-agnostic” message queue
Контекст:
Работая на Go, автор вдохновился инструментами из Node.js экосистемы (BullMQ, RabbitMQ) и захотел сделать что-то похожее, но с нуля, без зависимостей. Так родилась идея — сначала он создал Gocq (Go Concurrent Queue): простую concurrent-очередь, работающую через каналы.
⚡ Основная проблема
Gocq отлично работал в памяти, но не поддерживал устойчивое хранение задач.
Автор задумался: а можно ли сделать очередь, не зависящую от конкретного хранилища — так, чтобы её можно было подключить к Redis, SQLite или совсем без них?
🧱 Как это реализовано в VarMQ
После рефакторинга Gocq был разделён на два компонента:
1) Worker pool — пул воркеров, обрабатывающих задачи
2) Queue interface — абстракция над очередью, не зависящая от реализации
Теперь воркер просто берёт задачи из очереди, не зная, где они хранятся.
🧠 Пример использования
• In-memory очередь:
• С SQLite-поддержкой:
• С Redis (для распределённой обработки):
В итоге воркер обрабатывает задачи одинаково — независимо от хранилища.
✅ Почему это круто
• Гибкость: адаптеры позволяют легко менять хранилище без правок воркера
• Минимальные зависимости: в яд
📌 Читать
Контекст:
Работая на Go, автор вдохновился инструментами из Node.js экосистемы (BullMQ, RabbitMQ) и захотел сделать что-то похожее, но с нуля, без зависимостей. Так родилась идея — сначала он создал Gocq (Go Concurrent Queue): простую concurrent-очередь, работающую через каналы.
⚡ Основная проблема
Gocq отлично работал в памяти, но не поддерживал устойчивое хранение задач.
Автор задумался: а можно ли сделать очередь, не зависящую от конкретного хранилища — так, чтобы её можно было подключить к Redis, SQLite или совсем без них?
🧱 Как это реализовано в VarMQ
После рефакторинга Gocq был разделён на два компонента:
1) Worker pool — пул воркеров, обрабатывающих задачи
2) Queue interface — абстракция над очередью, не зависящая от реализации
Теперь воркер просто берёт задачи из очереди, не зная, где они хранятся.
🧠 Пример использования
• In-memory очередь:
w := varmq.NewVoidWorker(func(data any) {
// обработка задачи
}, 2)
q := w.BindQueue()
• С SQLite-поддержкой:
import "github.com/goptics/sqliteq"
db := sqliteq.New("test.db")
pq, _ := db.NewQueue("orders")
q := w.WithPersistentQueue(pq)
• С Redis (для распределённой обработки):
import "github.com/goptics/redisq"
rdb := redisq.New("redis://localhost:6379")
pq := rdb.NewDistributedQueue("transactions")
q := w.WithDistributedQueue(pq)
В итоге воркер обрабатывает задачи одинаково — независимо от хранилища.
✅ Почему это круто
• Гибкость: адаптеры позволяют легко менять хранилище без правок воркера
• Минимальные зависимости: в яд
📌 Читать
🧠 Уровень Pro: Медиана, ранги и NULL в Oracle SQL
📋 Есть таблица
📦 Данные:
🎯 Задача 2.0:
Вывести
и показать ранг продавца внутри региона по сумме продаж, где NULL = 0.
⚠ Подвохи:
-
- Нужно предварительно агрегировать суммы.
- Продавцы с только NULL-продажами = 0.
- Ранг должен учитывать правильную сортировку и связи с регионом.
✅ Решение:
```sql
WITH sales_total AS (
SELECT
salesman_id,
region,
NVL(SUM(amount), 0) AS total_sales
FROM sales
GROUP BY salesman_id, region
),
region_median AS (
SELECT
region,
MEDIAN(total_sales) AS region_median
FROM sales_total
GROUP BY region
),
ranked AS (
SELECT
st.salesman_id,
st.region,
st.total_sales,
r.region_median,
RANK() OVER (PARTITION BY st.region ORDER BY st.total_sales DESC) AS sales_rank
FROM sales_total st
JOIN region_median r ON st.region = r.region
)
SELECT *
FROM ranked
WHERE total_sales < region_median;
```
🧠 Объяснение:
1. `sales_total`: агрегируем продажи по продавцу, `NULL → 0`
2. `region_median`: считаем **медиану** продаж по каждому региону
3. `ranked`: добавляем `RANK()` по убыванию продаж внутри региона
4. Финальный фильтр: продажи ниже медианы
🔍 Пример вывода:
📌 Польза:
✅ Отлично проверяет:
- знание оконных функций
- работу с медианой
- поведение `NULL` в агрегатах
- построение CTE-цепочек и аналитики
🔁 Можно расширить:
- Добавить ранги *по убыванию и по возрастанию*
- Вместо `MEDIAN()` использовать `PERCENTILE_CONT()`
- Построить дэшборд: кто всегда "ниже медианы" за месяц
@sqlhub
📋 Есть таблица
sales
:
CREATE TABLE sales (
salesman_id NUMBER,
region VARCHAR2(50),
amount NUMBER
);
📦 Данные:
| salesman_id | region | amount |
|-------------|------------|--------|
| 101 | 'North' | 200 |
| 101 | 'North' | NULL |
| 102 | 'North' | 150 |
| 103 | 'North' | NULL |
| 104 | 'South' | 300 |
| 105 | 'South' | NULL |
| 106 | 'South' | 50 |
| 107 | 'South' | NULL |
🎯 Задача 2.0:
Вывести
salesman_id
, чья сумма продаж меньше медианы по региону, и показать ранг продавца внутри региона по сумме продаж, где NULL = 0.
⚠ Подвохи:
-
MEDIAN()
доступен только в Oracle.- Нужно предварительно агрегировать суммы.
- Продавцы с только NULL-продажами = 0.
- Ранг должен учитывать правильную сортировку и связи с регионом.
✅ Решение:
```sql
WITH sales_total AS (
SELECT
salesman_id,
region,
NVL(SUM(amount), 0) AS total_sales
FROM sales
GROUP BY salesman_id, region
),
region_median AS (
SELECT
region,
MEDIAN(total_sales) AS region_median
FROM sales_total
GROUP BY region
),
ranked AS (
SELECT
st.salesman_id,
st.region,
st.total_sales,
r.region_median,
RANK() OVER (PARTITION BY st.region ORDER BY st.total_sales DESC) AS sales_rank
FROM sales_total st
JOIN region_median r ON st.region = r.region
)
SELECT *
FROM ranked
WHERE total_sales < region_median;
```
🧠 Объяснение:
1. `sales_total`: агрегируем продажи по продавцу, `NULL → 0`
2. `region_median`: считаем **медиану** продаж по каждому региону
3. `ranked`: добавляем `RANK()` по убыванию продаж внутри региона
4. Финальный фильтр: продажи ниже медианы
🔍 Пример вывода:
| salesman_id | region | total_sales | region_median | sales_rank |
|-------------|--------|-------------|----------------|-------------|
| 105 | South | 0 | 50 | 3 |
| 107 | South | 0 | 50 | 3 |
| 103 | North | 0 | 150 | 3 |
📌 Польза:
✅ Отлично проверяет:
- знание оконных функций
- работу с медианой
- поведение `NULL` в агрегатах
- построение CTE-цепочек и аналитики
🔁 Можно расширить:
- Добавить ранги *по убыванию и по возрастанию*
- Вместо `MEDIAN()` использовать `PERCENTILE_CONT()`
- Построить дэшборд: кто всегда "ниже медианы" за месяц
@sqlhub
🧠 SQL-задача с подвохом: кто на самом деле опоздал?
У тебя есть таблица с логами входа сотрудников в офис. Но задача не в том, чтобы просто найти "кто пришёл позже 9:00", а выяснить кого стоит считать реально опоздавшим, если учесть такую бизнес-логику:
> Сотрудники входят в офис через турникет. Иногда турникет сканирует пропуск с задержкой, а иногда — несколько сотрудников входят подряд. Поэтому, если кто-то зашёл не позже, чем через 2 минуты после своего коллеги из той же команды — его не считают опоздавшим.
📊 Данные
Пример данных:
🎯 Задача
Напиши SQL-запрос, который определяет реально опоздавших сотрудников, если:
1. Время входа позже
2. Они не шли следом за коллегой из своей команды (разница входа больше 2 минут)
3. Один и тот же сотрудник не может быть "оправдан" несколькими — ищем только ближайшего предыдущего по времени из своей команды
💡 Подсказка: тут нужны:
- оконные функции (`LAG`)
- фильтрация по
- расчёт интервалов времени
- доп. условия на время и порядок
Реальное мышление аналитика начинается там, где бизнес-логика важнее простых фильтров.
✅ Решение:
```sql
WITH logs_with_prev AS (
SELECT
employee_id,
team_id,
entry_time,
LAG(entry_time) OVER (
PARTITION BY team_id
ORDER BY entry_time
) AS prev_entry_time
FROM office_logs
),
marked_late AS (
SELECT
*,
EXTRACT(EPOCH FROM (entry_time - prev_entry_time)) AS seconds_diff
FROM logs_with_prev
)
SELECT
employee_id,
team_id,
entry_time
FROM marked_late
WHERE
entry_time::time > '09:00:00'
AND (
prev_entry_time IS NULL
OR EXTRACT(EPOCH FROM (entry_time - prev_entry_time)) > 120
);
```
🔍 **Что происходит:**
• Сначала `LAG` находит предыдущего входившего из той же команды
• Затем считаем, сколько секунд прошло между входами
• Если прошло больше 2 минут или сотрудник был первым — он **реально опоздал**
📦 Такое решение пригодится, если нужно учитывать **контекст** и **временные связи**, а не просто жёсткие фильтры.
@sqlhub
У тебя есть таблица с логами входа сотрудников в офис. Но задача не в том, чтобы просто найти "кто пришёл позже 9:00", а выяснить кого стоит считать реально опоздавшим, если учесть такую бизнес-логику:
> Сотрудники входят в офис через турникет. Иногда турникет сканирует пропуск с задержкой, а иногда — несколько сотрудников входят подряд. Поэтому, если кто-то зашёл не позже, чем через 2 минуты после своего коллеги из той же команды — его не считают опоздавшим.
📊 Данные
CREATE TABLE office_logs (
employee_id INT,
team_id INT,
entry_time TIMESTAMP
);
Пример данных:
| employee_id | team_id | entry_time |
|-------------|---------|---------------------|
| 1 | 10 | 2024-01-01 08:59:10 |
| 2 | 10 | 2024-01-01 09:00:50 |
| 3 | 10 | 2024-01-01 09:02:20 |
| 4 | 20 | 2024-01-01 09:03:00 |
| 5 | 20 | 2024-01-01 09:04:40 |
| 6 | 20 | 2024-01-01 09:10:00 |
🎯 Задача
Напиши SQL-запрос, который определяет реально опоздавших сотрудников, если:
1. Время входа позже
09:00:00
2. Они не шли следом за коллегой из своей команды (разница входа больше 2 минут)
3. Один и тот же сотрудник не может быть "оправдан" несколькими — ищем только ближайшего предыдущего по времени из своей команды
💡 Подсказка: тут нужны:
- оконные функции (`LAG`)
- фильтрация по
team_id
- расчёт интервалов времени
- доп. условия на время и порядок
Реальное мышление аналитика начинается там, где бизнес-логика важнее простых фильтров.
✅ Решение:
```sql
WITH logs_with_prev AS (
SELECT
employee_id,
team_id,
entry_time,
LAG(entry_time) OVER (
PARTITION BY team_id
ORDER BY entry_time
) AS prev_entry_time
FROM office_logs
),
marked_late AS (
SELECT
*,
EXTRACT(EPOCH FROM (entry_time - prev_entry_time)) AS seconds_diff
FROM logs_with_prev
)
SELECT
employee_id,
team_id,
entry_time
FROM marked_late
WHERE
entry_time::time > '09:00:00'
AND (
prev_entry_time IS NULL
OR EXTRACT(EPOCH FROM (entry_time - prev_entry_time)) > 120
);
```
🔍 **Что происходит:**
• Сначала `LAG` находит предыдущего входившего из той же команды
• Затем считаем, сколько секунд прошло между входами
• Если прошло больше 2 минут или сотрудник был первым — он **реально опоздал**
📦 Такое решение пригодится, если нужно учитывать **контекст** и **временные связи**, а не просто жёсткие фильтры.
@sqlhub
SQL_cheatsheet.pdf
754.9 KB
⚡️ SQL-шпаргалка, которая выручит в интервью, проекте и проде
Полный мастер-гайд по SQL в одном PDF: практичные примеры, чёткие объяснения и никакой воды.
Что внутри:
• 💬 Создание баз, таблиц и изменение схем
• 💬 Запросы любого уровня сложности: JOIN, GROUP BY, HAVING, PARTITION
• 💬 Подзапросы, CTE, оконные функции: ROW_NUMBER, RANK, DENSE_RANK
• 💬 VIEW, временные таблицы и работа с дубликатами
• 💬 Даты, строки, преобразования и агрегации
• 💬 Очистка данных, разбиение по разделителям
• 💬 UNION, INTERSECT, EXCEPT — управление сложными выборками
Затрагиваются и продвинутые кейсы:
• Парсинг адресов
• Кастомная сортировка
• Использование ISNULL и COALESCE
🧠 Это не просто набор команд — это концентрат боевого SQL-опыта.
Подходит для:
➡️ Подготовки к SQL-интервью
➡️ BI и аналитики
➡️ Web-разработки с базами
➡️ Встраивания SQL в проекты на Python, Go, Java и других языках
Полный мастер-гайд по SQL в одном PDF: практичные примеры, чёткие объяснения и никакой воды.
Что внутри:
• 💬 Создание баз, таблиц и изменение схем
• 💬 Запросы любого уровня сложности: JOIN, GROUP BY, HAVING, PARTITION
• 💬 Подзапросы, CTE, оконные функции: ROW_NUMBER, RANK, DENSE_RANK
• 💬 VIEW, временные таблицы и работа с дубликатами
• 💬 Даты, строки, преобразования и агрегации
• 💬 Очистка данных, разбиение по разделителям
• 💬 UNION, INTERSECT, EXCEPT — управление сложными выборками
Затрагиваются и продвинутые кейсы:
• Парсинг адресов
• Кастомная сортировка
• Использование ISNULL и COALESCE
🧠 Это не просто набор команд — это концентрат боевого SQL-опыта.
Подходит для:
➡️ Подготовки к SQL-интервью
➡️ BI и аналитики
➡️ Web-разработки с базами
➡️ Встраивания SQL в проекты на Python, Go, Java и других языках
🦆 DuckDB теперь дружит с scikit-learn — мощный дуэт для ML-прототипов
В свежем гайде от 16 мая 2025 команда DuckDB показывает, как использовать их аналитическую СУБД вместе с scikit-learn — чтобы максимально быстро и удобно прототипировать модели машинного обучения.
💡 Пример — классификация пингвинов (датасет Palmer Penguins):
🔸 Предобработка в DuckDB:
Удаление NULL-ов, фильтрация, типизация.
Категориальные признаки кодируются через референс-таблицы (вместо LabelEncoder).
Используется selection_query с ленивым выполнением — данные грузятся только при необходимости.
🔸 Интеграция с scikit-learn:
Извлекаем pandas DataFrame прямо из DuckDB.
Обучаем классификатор (например, RandomForestClassifier) по подготовленным данным.
🛠 Идеально для:
• Быстрого прототипирования моделей
• Малых и средних наборов данных
• Python-разработчиков, которым не хочется возиться с SQL-серверами
📎 Подробнее:
https://duckdb.org/2025/05/16/scikit-learn-duckdb.html
@sqlhub
В свежем гайде от 16 мая 2025 команда DuckDB показывает, как использовать их аналитическую СУБД вместе с scikit-learn — чтобы максимально быстро и удобно прототипировать модели машинного обучения.
💡 Пример — классификация пингвинов (датасет Palmer Penguins):
🔸 Предобработка в DuckDB:
Удаление NULL-ов, фильтрация, типизация.
Категориальные признаки кодируются через референс-таблицы (вместо LabelEncoder).
Используется selection_query с ленивым выполнением — данные грузятся только при необходимости.
🔸 Интеграция с scikit-learn:
Извлекаем pandas DataFrame прямо из DuckDB.
Обучаем классификатор (например, RandomForestClassifier) по подготовленным данным.
🛠 Идеально для:
• Быстрого прототипирования моделей
• Малых и средних наборов данных
• Python-разработчиков, которым не хочется возиться с SQL-серверами
📎 Подробнее:
https://duckdb.org/2025/05/16/scikit-learn-duckdb.html
@sqlhub
YTsaurus, разработанная в Яндексе платформа для хранения и обработки больших данных, стала доступна как управляемый сервис в Yandex Cloud.
До 2023 года YTsaurus использовалась только внутри компании - для обучения нейросетей, аналитики, обработки телеметрии и работы с поисковым индексом. В прошлом году платформу выложили в опенсорс, и с тех пор она применяется как внутри Яндекса, так и за его пределами.
Теперь YTsaurus можно развернуть в облаке - без ручной настройки и с поддержкой от команды Яндекса. Платформа работает с эксабайтами данных, масштабируется до миллиона CPU и десятков тысяч GPU, поддерживает ClickHouse, Spark, MapReduce и подходит для любых сценариев - от ETL до построения хранилищ.
Заявки на ранний доступ уже открыты.
До 2023 года YTsaurus использовалась только внутри компании - для обучения нейросетей, аналитики, обработки телеметрии и работы с поисковым индексом. В прошлом году платформу выложили в опенсорс, и с тех пор она применяется как внутри Яндекса, так и за его пределами.
Теперь YTsaurus можно развернуть в облаке - без ручной настройки и с поддержкой от команды Яндекса. Платформа работает с эксабайтами данных, масштабируется до миллиона CPU и десятков тысяч GPU, поддерживает ClickHouse, Spark, MapReduce и подходит для любых сценариев - от ETL до построения хранилищ.
Заявки на ранний доступ уже открыты.
🎯 SQL-задача с подвохом для аналитиков
Таблица
📌 Задача:
Найди имя продавца, который заработал максимальную сумму за каждый месяц.
🧠 Подвох:
Многие пытаются использовать
💡 Подсказки:
• Сначала сгруппируй продажи по
• Посчитай
• Используй оконную функцию
• Отфильтруй только те строки, где
🧩 Решение:
👀 Бонус-вопрос:
Что будет, если у двух продавцов одинаковая сумма за месяц?
Какой оконной функцией это корректно учесть?
👉
📌 Отличная задача, чтобы проверить знание оконных функций и работы с агрегацией в SQL.
@sqlhub
Таблица
sales
:
CREATE TABLE sales (
id SERIAL PRIMARY KEY,
seller_name VARCHAR,
sale_amount NUMERIC,
sale_date DATE
);
📌 Задача:
Найди имя продавца, который заработал максимальную сумму за каждый месяц.
🧠 Подвох:
Многие пытаются использовать
GROUP BY month, seller_name
и MAX()
, но это не даст имя продавца — только сумму. Нужно вернуть имя лучшего продавца за месяц. А если таких несколько? Тоже учти.💡 Подсказки:
• Сначала сгруппируй продажи по
month
и seller_name
• Посчитай
SUM(sale_amount)
• Используй оконную функцию
RANK()
или ROW_NUMBER()
• Отфильтруй только те строки, где
rank = 1
🧩 Решение:
WITH monthly_totals AS (
SELECT
DATE_TRUNC('month', sale_date) AS month,
seller_name,
SUM(sale_amount) AS total
FROM sales
GROUP BY 1, 2
),
ranked AS (
SELECT *,
RANK() OVER (PARTITION BY month ORDER BY total DESC) AS rnk
FROM monthly_totals
)
SELECT month, seller_name, total
FROM ranked
WHERE rnk = 1
ORDER BY month;
👀 Бонус-вопрос:
Что будет, если у двух продавцов одинаковая сумма за месяц?
Какой оконной функцией это корректно учесть?
👉
RANK()
вернёт обоих, ROW_NUMBER()
— только одного.📌 Отличная задача, чтобы проверить знание оконных функций и работы с агрегацией в SQL.
@sqlhub
🛠️ Что нового в SQLite — свежие обновления и улучшения
🔗 https://www.sqlite.org/changes.html
SQLite — одна из самых популярных встраиваемых баз данных в мире, и каждое обновление приносит не только исправления, но и серьёзные улучшения производительности и безопасности.
Вот ключевые изменения из последних версий:
🆕 SQLite 3.46.0 (май 2024)
- Добавлена поддержка
- Новый флаг
- Оптимизации для
- Улучшено поведение
🧪 Расширенные тесты:
- SQLite теперь использует дополнительный fuzzing для анализа стабильности ядра при высоких нагрузках и необычных SQL
🧹 Также исправлены:
- Ошибки в индексах при сложной комбинации
- Утечка памяти при специфическом использовании
💡 SQLite остаётся одной из самых лёгких, надёжных и удобных баз данных, которую можно использовать буквально везде: от браузеров и мобильных приложений до IoT и CLI-утилит.
📚 Полный список изменений — здесь:
https://www.sqlite.org/changes.html
@sqlhub
🔗 https://www.sqlite.org/changes.html
SQLite — одна из самых популярных встраиваемых баз данных в мире, и каждое обновление приносит не только исправления, но и серьёзные улучшения производительности и безопасности.
Вот ключевые изменения из последних версий:
🆕 SQLite 3.46.0 (май 2024)
- Добавлена поддержка
contentless-delete
для таблиц FTS5 — меньше места, выше скорость - Новый флаг
SQLITE_DBCONFIG_STMT_SCANSTATUS
— можно отключать сбор статистики по выполнению запросов - Оптимизации для
LEFT JOIN
+ OR
условий в WHERE
— запросы выполняются заметно быстрее - Улучшено поведение
WITHOUT ROWID
таблиц с составными ключами🧪 Расширенные тесты:
- SQLite теперь использует дополнительный fuzzing для анализа стабильности ядра при высоких нагрузках и необычных SQL
🧹 Также исправлены:
- Ошибки в индексах при сложной комбинации
JOIN + USING
- Утечка памяти при специфическом использовании
PRAGMA function_list
💡 SQLite остаётся одной из самых лёгких, надёжных и удобных баз данных, которую можно использовать буквально везде: от браузеров и мобильных приложений до IoT и CLI-утилит.
📚 Полный список изменений — здесь:
https://www.sqlite.org/changes.html
@sqlhub
📧🤖 ART: интеллектуальный e-mail-агент с памятью, действиями и "мыслями"
OpenPipe представили подробный разбор архитектуры ART (Action–Recall–Thought) — это не просто бот, а полноценный агент, который может читать письма, анализировать контекст, планировать действия и запоминать диалог. Такой себе LLM-секретарь, который не забывает, что вы писали неделю назад, и умеет реагировать правильно.
🧠 Что такое ART?
ART — это архитектура, построенная вокруг трёх основных элементов:
1️⃣ Action — агент может действовать: писать ответы, создавать события, ставить задачи, отправлять follow-up.
2️⃣ Recall — агент вспоминает: использует векторную память, чтобы помнить важные детали переписки.
3️⃣ Thought — агент думает: размышляет о контексте, выбирает нужные шаги и обновляет своё внутреннее состояние.
Каждый запуск агента — это один цикл мышления, в котором он анализирует новое письмо, сравнивает его с памятью и решает, что делать.
🧩 Как работает?
Архитектура построена на LangGraph — фреймворке для создания LLM-агентов с управляемыми потоками данных (узлы, переходы, состояния).
🧬 Компоненты:
- Nodes:
-
-
-
-
-
- Memory:
- Используется ChromaDB (векторная база), куда сохраняются ключевые сообщения, решения, действия и мысли.
- Tools:
- Встроенные функции-агенты (tools) для генерации писем, событий, напоминаний, оповещений и т.п.
- Всё вызывается динамически через LLM, как в OpenAI function calling.
🔁 Как агент работает на практике?
Пример цикла:
1. Приходит e-mail →
2.
3.
4.
5.
Следующее письмо будет уже обрабатываться с учётом прошлого контекста. Агент понимает цепочку, тему, задачи и автоматически действует.
💡 Что делает ART особенным?
✅ Работает в несколько итераций, не просто «prompt → response»
✅ Помнит прошлые письма, решения, даже ошибки
✅ Сам планирует, что делать: отвечать, пересылать, напоминать
✅ Обновляет свои действия при изменении входных данных
✅ Настраивается под любые задачи: продажи, саппорт, личные письма, менеджмент
📎 Полный разбор от OpenPipe с примерами кода, схемами и демонстрацией:
👉 https://openpipe.ai/blog/art-e-mail-agent
Если ты хочешь строить LLM-агентов с настоящей памятью и логикой — это must-read. Это шаг к настоящим автономным ассистентам.
#AI #LLM #autonomousagents #LangGraph #e-mail #productivity #openpipe #инструменты
@sqlhub
OpenPipe представили подробный разбор архитектуры ART (Action–Recall–Thought) — это не просто бот, а полноценный агент, который может читать письма, анализировать контекст, планировать действия и запоминать диалог. Такой себе LLM-секретарь, который не забывает, что вы писали неделю назад, и умеет реагировать правильно.
🧠 Что такое ART?
ART — это архитектура, построенная вокруг трёх основных элементов:
1️⃣ Action — агент может действовать: писать ответы, создавать события, ставить задачи, отправлять follow-up.
2️⃣ Recall — агент вспоминает: использует векторную память, чтобы помнить важные детали переписки.
3️⃣ Thought — агент думает: размышляет о контексте, выбирает нужные шаги и обновляет своё внутреннее состояние.
Каждый запуск агента — это один цикл мышления, в котором он анализирует новое письмо, сравнивает его с памятью и решает, что делать.
🧩 Как работает?
Архитектура построена на LangGraph — фреймворке для создания LLM-агентов с управляемыми потоками данных (узлы, переходы, состояния).
🧬 Компоненты:
- Nodes:
-
Reader
: разбирает новое письмо -
Memory Retriever
: ищет релевантные воспоминания -
Planner
: решает, что делать -
Executor
: выполняет действия (ответ, событие и т.д.) -
Reflector
: обновляет размышления агента- Memory:
- Используется ChromaDB (векторная база), куда сохраняются ключевые сообщения, решения, действия и мысли.
- Tools:
- Встроенные функции-агенты (tools) для генерации писем, событий, напоминаний, оповещений и т.п.
- Всё вызывается динамически через LLM, как в OpenAI function calling.
🔁 Как агент работает на практике?
Пример цикла:
1. Приходит e-mail →
Reader
извлекает суть.2.
Memory Retriever
ищет похожие прошлые переписки.3.
Planner
решает: ответить? создать задачу? проигнорировать?4.
Executor
выполняет нужное действие.5.
Reflector
обновляет память и размышления.Следующее письмо будет уже обрабатываться с учётом прошлого контекста. Агент понимает цепочку, тему, задачи и автоматически действует.
💡 Что делает ART особенным?
✅ Работает в несколько итераций, не просто «prompt → response»
✅ Помнит прошлые письма, решения, даже ошибки
✅ Сам планирует, что делать: отвечать, пересылать, напоминать
✅ Обновляет свои действия при изменении входных данных
✅ Настраивается под любые задачи: продажи, саппорт, личные письма, менеджмент
📎 Полный разбор от OpenPipe с примерами кода, схемами и демонстрацией:
👉 https://openpipe.ai/blog/art-e-mail-agent
Если ты хочешь строить LLM-агентов с настоящей памятью и логикой — это must-read. Это шаг к настоящим автономным ассистентам.
#AI #LLM #autonomousagents #LangGraph #e-mail #productivity #openpipe #инструменты
@sqlhub
🧠 Хитрая задача по SQL: максимум без агрегатов?
У тебя есть таблица
📌 Задача:
Для каждого клиента (`customer_id`) найти наиболее поздний заказ (по
🔥 Уловка:
💡 Подумай:
Как ты решишь эту задачу только с
📥 Ожидаемый результат:
```
🧩 Подсказка:
Можно использовать
📎 Такой приём полезен:
• Когда нельзя использовать оконные функции
• Когда ты работаешь на старых версиях СУБД
• Когда нужна универсальность между MySQL / Oracle / SQLite
#SQL #Задача #БазыДанных #DataEngineering #Оптимизация
@sqlhub
У тебя есть таблица
orders
со следующими полями:
orders(id, customer_id, order_date, amount)
📌 Задача:
Для каждого клиента (`customer_id`) найти наиболее поздний заказ (по
order_date`), **не используя `GROUP BY
и `MAX()`**.🔥 Уловка:
DISTINCT ON
, TOP 1 WITH TIES
и RANK()
нельзя — ты ограничен базовым SQL, работающим на большинстве СУБД.💡 Подумай:
Как ты решишь эту задачу только с
JOIN
, WHERE
и EXISTS
?📥 Ожидаемый результат:
```sql
customer_id | order_id | order_date | amount
------------|----------|------------|--------
1001 | 87 | 2024-12-01 | 320.00
1002 | 91 | 2024-12-05 | 175.00
...
```
🧩 Подсказка:
Можно использовать
NOT EXISTS
, чтобы выбрать заказы, у которых нет более новых у того же клиента.
SELECT o.*
FROM orders o
WHERE NOT EXISTS (
SELECT 1
FROM orders o2
WHERE o2.customer_id = o.customer_id
AND o2.order_date > o.order_date
)
📎 Такой приём полезен:
• Когда нельзя использовать оконные функции
• Когда ты работаешь на старых версиях СУБД
• Когда нужна универсальность между MySQL / Oracle / SQLite
#SQL #Задача #БазыДанных #DataEngineering #Оптимизация
@sqlhub
Сейчас каждая компания собирает тонны данных: продажи, клиенты, маркетинг, логистика. Но сырые цифры бесполезны, если их нельзя превратить в понятные отчёты и выводы.
Приглашаем вас на вебинар 3 июня в 18:30 по МСК, где наш новый спикер — Владислав Вареник, Data Engineer в Сравни.ру — расскажет кто такие дата-инженеры и как они ускоряют работу бизнеса.
Что вы узнаете на вебинаре?
Даже если вы далеки от аналитики — покажем, как начать с нуля и быстро получить результат. Не упустите шанс научиться тому, что будет цениться ещё десятки лет! 🚀
🕗 Встречаемся 3 июня в 18:30 по МСК
Please open Telegram to view this post
VIEW IN TELEGRAM
🚀 Как построить ML-пайплайн в Apache Spark: пошаговый гайд
В свежей статье на KDnuggets рассматривается, как с помощью Apache Spark и библиотеки MLlib можно построить масштабируемый пайплайн машинного обучения для задач, таких как прогноз оттока клиентов.
🔧 Компоненты пайплайна:
- Transformers: преобразуют данные (например,
- Estimators: обучают модели (например, `LogisticRegression`)
- Pipeline: объединяет все шаги в единую последовательность
🧪 Пример:
1. Загрузка и очистка данных
2. Преобразование категориальных признаков
3. Сборка признаков в вектор
4. Масштабирование данных
5. Обучение модели логистической регрессии
6. Оценка качества модели (accuracy, precision, recall, F1)
📌 Ключевые преимущества:
- Высокая скорость обработки больших объемов данных
- Удобная интеграция с Python через PySpark
- Гибкость и масштабируемость для промышленных задач
Полный разбор с кодом и примерами:
👉 https://www.kdnuggets.com/implementing-machine-learning-pipelines-with-apache-spark
В свежей статье на KDnuggets рассматривается, как с помощью Apache Spark и библиотеки MLlib можно построить масштабируемый пайплайн машинного обучения для задач, таких как прогноз оттока клиентов.
🔧 Компоненты пайплайна:
- Transformers: преобразуют данные (например,
StringIndexer
, `StandardScaler`)- Estimators: обучают модели (например, `LogisticRegression`)
- Pipeline: объединяет все шаги в единую последовательность
🧪 Пример:
1. Загрузка и очистка данных
2. Преобразование категориальных признаков
3. Сборка признаков в вектор
4. Масштабирование данных
5. Обучение модели логистической регрессии
6. Оценка качества модели (accuracy, precision, recall, F1)
📌 Ключевые преимущества:
- Высокая скорость обработки больших объемов данных
- Удобная интеграция с Python через PySpark
- Гибкость и масштабируемость для промышленных задач
Полный разбор с кодом и примерами:
👉 https://www.kdnuggets.com/implementing-machine-learning-pipelines-with-apache-spark
Диплом vs курсы: золотая середина для карьеры в IT
Без профильного образования в IT можно расти, но для серьезных позиций часто нужен диплом. На помощь приходит магистратура и онлайн-курсы, но проблема в том, что обучение в вузе сложно совмещать с работой, а короткие онлайн-курсы дают лишь поверхностные знания.
6 июня в 18:00 (мск) Анатолий Карпов (автор онлайн-курсов по Data Science) и Евгений Соколов (научный руководитель ФКН НИУ ВШЭ) расскажут о совместной онлайн-магистратуре karpov courses и НИУ ВШЭ — «Аналитика больших данных» на бесплатном вебинаре.
От ВШЭ — экспертиза и опыт одного из крупнейших вузов России, а от karpov courses — практические навыки в сфере анализа данных.
На встрече вы узнаете:
- преимущества высшего онлайн-образования и какие тренды есть на рынке;
- какие этапы необходимо пройти, чтобы поступить в онлайн-магистратуру НИУ ВШЭ и karpov courses;
- почему так популярна и востребована сфера аналитики данных в 2025 году.
Присоединяйтесь ко дню открытых дверей онлайн-магистратуры «Аналитика больших данных» от НИУ ВШЭ и karpov courses: https://clc.to/erid_2W5zFHNZGxY
Реклама. ООО "КАРПОВ КУРСЫ". ИНН 7811764627. erid: 2W5zFHNZGxY.
Без профильного образования в IT можно расти, но для серьезных позиций часто нужен диплом. На помощь приходит магистратура и онлайн-курсы, но проблема в том, что обучение в вузе сложно совмещать с работой, а короткие онлайн-курсы дают лишь поверхностные знания.
6 июня в 18:00 (мск) Анатолий Карпов (автор онлайн-курсов по Data Science) и Евгений Соколов (научный руководитель ФКН НИУ ВШЭ) расскажут о совместной онлайн-магистратуре karpov courses и НИУ ВШЭ — «Аналитика больших данных» на бесплатном вебинаре.
От ВШЭ — экспертиза и опыт одного из крупнейших вузов России, а от karpov courses — практические навыки в сфере анализа данных.
На встрече вы узнаете:
- преимущества высшего онлайн-образования и какие тренды есть на рынке;
- какие этапы необходимо пройти, чтобы поступить в онлайн-магистратуру НИУ ВШЭ и karpov courses;
- почему так популярна и востребована сфера аналитики данных в 2025 году.
Присоединяйтесь ко дню открытых дверей онлайн-магистратуры «Аналитика больших данных» от НИУ ВШЭ и karpov courses: https://clc.to/erid_2W5zFHNZGxY
Реклама. ООО "КАРПОВ КУРСЫ". ИНН 7811764627. erid: 2W5zFHNZGxY.
🧠 SQL-задача с подвохом: "Невидимые дубликаты"
В таблице
🎯 Цель:
Найти количество уникальных пользователей, если:
- Регистр не учитывается (`alice` = `ALICE`)
- Пробелы игнорируются
- Для
— Убираются точки в имени
— Всё после
✅ SQL-решение:
🔍 Как это работает:
LOWER(TRIM(email)) — убираем пробелы и регистр
SPLIT_PART(..., '+', 1) — отрезаем всё после +
REGEXP_REPLACE(..., '\.', '', 'g') — удаляем точки
Считаем DISTINCT, чтобы получить число уникальных email'ов
🔥 Используй такие трюки для:
• антифрода
• чистки базы
• аналитики поведения пользователей
#SQL #PostgreSQL #Gmail #EmailNormalization #DevTools #AntiFraud #DataCleaning #Analytics
В таблице
users
хранятся email-адреса пользователей. Некоторые юзеры регистрируются повторно, маскируя один и тот же email по-разному:| id | name | email |
|----|----------|--------------------------|
| 1 | Alice | [email protected] |
| 2 | Bob | [email protected] |
| 3 | Charlie | [email protected] |
| 4 | Dave | [email protected] |
| 5 | Eve | [email protected] |
🎯 Цель:
Найти количество уникальных пользователей, если:
- Регистр не учитывается (`alice` = `ALICE`)
- Пробелы игнорируются
- Для
@gmail.com
: — Убираются точки в имени
— Всё после
+
отрезается✅ SQL-решение:
SELECT COUNT(DISTINCT normalized_email) AS unique_users
FROM (
SELECT
CASE
WHEN email ILIKE '%@gmail.com' THEN
REGEXP_REPLACE(
SPLIT_PART(SPLIT_PART(LOWER(TRIM(email)), '+', 1), '@', 1),
'\.', '', 'g'
) || '@gmail.com'
ELSE
LOWER(REPLACE(TRIM(email), ' ', ''))
END AS normalized_email
FROM users
) AS cleaned;
🔍 Как это работает:
LOWER(TRIM(email)) — убираем пробелы и регистр
SPLIT_PART(..., '+', 1) — отрезаем всё после +
REGEXP_REPLACE(..., '\.', '', 'g') — удаляем точки
Считаем DISTINCT, чтобы получить число уникальных email'ов
🔥 Используй такие трюки для:
• антифрода
• чистки базы
• аналитики поведения пользователей
#SQL #PostgreSQL #Gmail #EmailNormalization #DevTools #AntiFraud #DataCleaning #Analytics
Redis и Valkey – изучите секреты самых популярных open source key-value СУБД
В высоко-нагруженных сервисах Redis — не просто кэш, а важная подсистема, на которой строится значимая часть бизнес-логики. От его стабильности, масштабируемости и отказоустойчивости зависит производительность всего сервиса. Valkey - это современный производительный форк Redis с открытым исходным кодом, поддерживаемый сообществом и рядом крупных компаний. Valkey набирает популярность, поддержан крупными облачными провайдерами, и вполне возможно потеснит или вовсе заменит Redis со временем. Наш курс — для тех, кто хочет держать свой стэк и знания актуальными и глубоко разбираться, как устроен Redis и Valkey.
🌐 В программе курса:
🤩 Как эффективно использовать базовые и продвинутые структуры данных: HyperLogLog, Bitmaps и Bisields, Streams, Geospatial-индексы, Bloom Filters
🤩 Как проектировать in-memory системы, которые не разваливаются под нагрузкой, что влияет на отказоустойчивость и как её добиться
🤩 Как работает репликация и кластеризация на практике (режимы Sentinel и Cluster)
🤩 Как встроить Redis/Valkey в реальный прод с учётом безопасности, интеграций и современных практик мониторинга.
🥸 Кто мы: R&D-центр Devhands. Автор курса — Константин Ратвин — преподаватель МФТИ на кафедре БИТ (совместно со СберТех), эксперт по распределённым системам и банковским ИТ, автор курсов по СУБД и инфраструктуре, спикер HighLoad++ и PGConf.
🗓 Старт курса: 9 июня, 6 недель обучения.
Изучить программу и записаться можно здесь.
Ждем вас!
Реклама. ИП Рыбак А.А. ИНН 771407709607 Erid: 2VtzqxNnFKA
В высоко-нагруженных сервисах Redis — не просто кэш, а важная подсистема, на которой строится значимая часть бизнес-логики. От его стабильности, масштабируемости и отказоустойчивости зависит производительность всего сервиса. Valkey - это современный производительный форк Redis с открытым исходным кодом, поддерживаемый сообществом и рядом крупных компаний. Valkey набирает популярность, поддержан крупными облачными провайдерами, и вполне возможно потеснит или вовсе заменит Redis со временем. Наш курс — для тех, кто хочет держать свой стэк и знания актуальными и глубоко разбираться, как устроен Redis и Valkey.
Изучить программу и записаться можно здесь.
Ждем вас!
Реклама. ИП Рыбак А.А. ИНН 771407709607 Erid: 2VtzqxNnFKA
Please open Telegram to view this post
VIEW IN TELEGRAM
📦 Outbox — надёжная реализация outbox-паттерна на Go для микросервисов
Если твои сервисы пишут в базу и одновременно публикуют события в Kafka, RabbitMQ или другие брокеры — знай: без outbox-паттерна ты рискуешь потерять данные.
🔧
🧠 Что она делает:
1. Сохраняет событие в таблицу
2. Отдельный воркер читает сообщения и отправляет их в брокер
3. После успешной доставки — сообщение помечается как доставленное
💡 Особенности:
- Поддержка PostgreSQL
- Готовые адаптеры для Kafka и RabbitMQ
- Возможность использовать свой брокер (реализуй интерфейс)
- Поддержка сериализации / форматирования событий
- Использует
🧩 Подходит для:
- надёжной синхронизации БД ↔ событий
- микросервисов, где важна консистентность
- систем, где нужна повторная доставка без дублей
🔥 Отличный выбор, если ты хочешь atomic-публикацию событий без тяжёлых фреймворков и сервисов.
#Go #OutboxPattern #Kafka #RabbitMQ #Microservices #EventDriven #PostgreSQL
🔗 https://github.com/oagudo/outbox
@sqlhub
Если твои сервисы пишут в базу и одновременно публикуют события в Kafka, RabbitMQ или другие брокеры — знай: без outbox-паттерна ты рискуешь потерять данные.
🔧
Outbox
— это лёгкая и удобная библиотека на Go, которая помогает сделать доставку сообщений атомарной и надёжной, без лишней сложности.🧠 Что она делает:
1. Сохраняет событие в таблицу
outbox
в рамках транзакции2. Отдельный воркер читает сообщения и отправляет их в брокер
3. После успешной доставки — сообщение помечается как доставленное
💡 Особенности:
- Поддержка PostgreSQL
- Готовые адаптеры для Kafka и RabbitMQ
- Возможность использовать свой брокер (реализуй интерфейс)
- Поддержка сериализации / форматирования событий
- Использует
sqlx
и стандартную database/sql
🧩 Подходит для:
- надёжной синхронизации БД ↔ событий
- микросервисов, где важна консистентность
- систем, где нужна повторная доставка без дублей
🔥 Отличный выбор, если ты хочешь atomic-публикацию событий без тяжёлых фреймворков и сервисов.
#Go #OutboxPattern #Kafka #RabbitMQ #Microservices #EventDriven #PostgreSQL
🔗 https://github.com/oagudo/outbox
@sqlhub
🚀 Solune — высокопроизводительная NoSQL-база данных на Go
Solune — это быстрая и гибкая NoSQL-база данных, разработанная с упором на масштабируемость, низкую задержку и производительность. Она использует приоритетную работу с данными в памяти, чтобы обеспечить молниеносный доступ и минимальную задержку при высоких нагрузках.
🧠 Почему Go?
Solune построена на Go — и вот почему это важно:
• Горутины и каналы — идеально для обработки тысяч запросов одновременно
• Высокая скорость исполнения — Go отлично подходит для чувствительных к производительности систем
• Простота и читаемость — легче поддерживать и развивать проект
• Богатая экосистема — множество библиотек и инструментов для создания надёжных систем
Фокус на хранении в памяти:
• Мгновенный доступ — чтение из памяти быстрее, чем с диска
• Минимальные задержки — нет тяжёлых операций I/O
• Гибкое масштабирование — просто увеличивайте объём RAM
💡 Подходит для:
• Высоконагруженных API
• Систем, где критична скорость доступа
• Приложений с минимальной допустимой задержкой
📌 Solune — это выбор для тех, кто ищет быструю, масштабируемую и современную NoSQL-БД, идеально подходящую для in-memory архитектур.
🔗 GitHub
@sqlhub
Solune — это быстрая и гибкая NoSQL-база данных, разработанная с упором на масштабируемость, низкую задержку и производительность. Она использует приоритетную работу с данными в памяти, чтобы обеспечить молниеносный доступ и минимальную задержку при высоких нагрузках.
Solune построена на Go — и вот почему это важно:
• Горутины и каналы — идеально для обработки тысяч запросов одновременно
• Высокая скорость исполнения — Go отлично подходит для чувствительных к производительности систем
• Простота и читаемость — легче поддерживать и развивать проект
• Богатая экосистема — множество библиотек и инструментов для создания надёжных систем
Фокус на хранении в памяти:
• Мгновенный доступ — чтение из памяти быстрее, чем с диска
• Минимальные задержки — нет тяжёлых операций I/O
• Гибкое масштабирование — просто увеличивайте объём RAM
💡 Подходит для:
• Высоконагруженных API
• Систем, где критична скорость доступа
• Приложений с минимальной допустимой задержкой
📌 Solune — это выбор для тех, кто ищет быструю, масштабируемую и современную NoSQL-БД, идеально подходящую для in-memory архитектур.
git clone https://github.com/thijsrijkers/solune.git
cd solune
🔗 GitHub
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM